package com.yneusoft.pctask.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yneusoft.common.handler.MyException;
import com.yneusoft.common.model.ResponseWrapper;
import com.yneusoft.common.tool.DataProcessing;
import com.yneusoft.dao.entity.Department;
import com.yneusoft.dao.entity.DepartmentStaff;
import com.yneusoft.dao.entity.DepartmentState;
import com.yneusoft.dao.mapper.DepartmentMapper;
import com.yneusoft.dao.mapper.DepartmentStaffMapper;
import com.yneusoft.dao.mapper.DepartmentStateMapper;
import com.yneusoft.pctask.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import static com.yneusoft.common.enums.ResultEnum.FAILED;

/**
 * @Description： 部门管理service层
 * @Author: wbf
 * @Date: 2021/11/24 16:30
 */
@Service
public class DepartmentManageService {
    //部门状态表mapper
    @Autowired
    DepartmentStateMapper departmentStateMapper;
    //部门表mapper
    @Autowired
    DepartmentMapper departmentMapper;
    //部门员工关联表
    @Autowired
    DepartmentStaffMapper departmentStaffMapper;

    /**
     * 1.获取部门状态列表
     *
     * @return 部门状态列表
     */
    public ResponseWrapper getDepartmentStateList() {
        return ResponseWrapper.markSuccess(DepartmentState.dataList);
    }

    /**
     * 2.获取部门列表
     *
     * @return 部门列表
     */
    public ResponseWrapper getDepartmentList(GetDepartmentListParam param) {
        //通过部门的aid和状态进行排序排序
        LambdaQueryWrapper<Department> getDepartmentList = new LambdaQueryWrapper<>();
        getDepartmentList
                .orderBy(true, false, Department::getStateId)
                .orderBy(true, true, Department::getAid);
        //获取部门信息列表
        List<GetDepartmentListByLevel> listAll = JSON.parseArray(JSON.toJSONString(departmentMapper.selectList(getDepartmentList)), GetDepartmentListByLevel.class);
        //循环遍历部门信息列表
        for (GetDepartmentListByLevel each : listAll) {
            //修改时间格式
            each.setCreateTime(each.getCreateTime().replace("T", " "));
        }
        //计算每个部门所含人数
        getStaffNum(listAll);

        //标注不能删除的部门 并找到他们的子部门 并计算部门人数
        for (GetDepartmentListByLevel each : listAll) {
            findChildren(listAll, each);
            if (each.getChildren().size() != 0 || each.getStaffNumber() > 0) {
                each.setCanDelete(false);
            }
        }

        //进行分页和查询
        IPage<Department> page = new Page<>(param.getPage(), param.getPageSize());
        //对部门状态进行判断
        if (param.getStateId() != null) {
            getDepartmentList.eq(Department::getStateId, param.getStateId());
        }
        //对部门名称模糊查询进行判断
        if (param.getSearchKey() != null) {
            getDepartmentList.like(Department::getName, param.getSearchKey());
        }
        //对部门的层级进行判断
        if (param.getStateId() == null && param.getSearchKey() == null) {
            getDepartmentList.eq(Department::getLevel, 0);
        }
        IPage<Department> departmentByCondition = departmentMapper.selectPage(page, getDepartmentList);
        List<Department> records = departmentByCondition.getRecords();

        //通过比对确定响应数据
        List<GetDepartmentListByLevel> listByLevel = new ArrayList<>();
        for (Department eachAid : records) {
            for (GetDepartmentListByLevel each : listAll) {
                if (eachAid.getAid().intValue() == each.getAid().intValue()) {
                    listByLevel.add(each);
                    break;
                }
            }
        }
        //获取对应部门的信息
        List<GetDepartmentList> list = JSON.parseArray(JSON.toJSONString(listByLevel), GetDepartmentList.class);

        //若是条件查询则不展示子部门
        for (GetDepartmentList each : list) {
            if (param.getSearchKey() != null || param.getStateId() != null) {
                each.setChildren(new ArrayList<>());
            }
        }

        //确定部门总数和响应数据条数
        Long rowsNum = departmentByCondition.getTotal();
        Long departmentNum = departmentMapper.selectCount(null).longValue();
        return ResponseWrapper.markSuccess(new GetDepartmentListResult(rowsNum, departmentNum, list));
    }

    /**
     * 计算部门员工总数 并将子部门初始化为空表
     * @param needCount 需要计算总数的部门列表
     */
    private void getStaffNum(List<GetDepartmentListByLevel> needCount) {
        //循环遍历子部门信息
        for (GetDepartmentListByLevel each : needCount) {
            //对子部门进行判断
            if (each.getChildren() == null) {
                each.setChildren(new ArrayList<>());
            }
            //获取子部门的总数
            LambdaQueryWrapper<DepartmentStaff> getStaffNum = new LambdaQueryWrapper<>();
            getStaffNum.eq(DepartmentStaff::getDepartmentAid, each.getAid());
            Integer number = departmentStaffMapper.selectCount(getStaffNum);
            each.setStaffNumber(number);
        }
    }

    /**
     * 获取某部门的子部门
     *
     * @param listAll 部门列表
     * @param farther 需要寻找子部门的父部门
     */
    private void findChildren(List<GetDepartmentListByLevel> listAll, GetDepartmentListByLevel farther) {
        List<GetDepartmentListByLevel> children = new ArrayList<>();
        //统计子部门人数
        Integer sum = farther.getStaffNumber();
        for (GetDepartmentListByLevel each : listAll) {
            //对父部门的信息进行判断
            if (each.getFatherAid() != null) {
                if (each.getFatherAid().intValue() == farther.getAid().intValue()) {
                    sum += each.getStaffNumber();
                    children.add(each);
                }
            }
        }
        farther.setChildren(children);
        farther.setStaffNumber(sum);
    }

    /**
     * 3、【新增/修改】启用/禁用部门
     *
     * @return 修改状态
     */
    public ResponseWrapper enableDepartment(EnableDepartmentParam param) {
        //通过部门的aid获取部门状态信息
        Department updateDepartmentState = departmentMapper.selectById(param.getAid());
        //对部门状态信息进行判断
        if (updateDepartmentState == null){
            return ResponseWrapper.markCustom(FAILED, "该部门不存在!刷新页面!");
        }
        //获取部门状态信息
        Integer stateId = updateDepartmentState.getStateId();
        //给状态进行赋值
        updateDepartmentState.setStateId(stateId == 0 ? 1 : 0);
        updateDepartmentState.setStateName(stateId == 0 ? "启用" : "禁用");
        //获取当前时间 更新修改时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String time = DataProcessing.getFormatTime(null);
        updateDepartmentState.setUpdateTime(LocalDateTime.parse(time, formatter));

        //修改部门状态信息
        departmentMapper.updateById(updateDepartmentState);
        return ResponseWrapper.markSuccess();
    }

    /**
     * 4、【新增/修改】修改时获取的部门信息
     *
     * @return 部门信息
     */
    public ResponseWrapper getDepartmentInfo(GetDepartmentInfoParam param) {
        //通过部门的aid获取部门信息
        Department department = departmentMapper.selectById(param.getAid());
        //对部门信息进行判断
        if (department == null) {
            throw new MyException("该部门不存在，请刷新页面！");
        }
        //获取对应的部门信息
        GetDepartmentInfoResult result = JSON.parseObject(JSON.toJSONString(department), GetDepartmentInfoResult.class);
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 5、【新增/修改】修改时获取部门列表
     *
     * @return 部门列表
     */
    public ResponseWrapper getDepartmentInfoList() {
        //获取对应部门的信息
        List<Department> departments = departmentMapper.selectList(null);
        List<GetDepartmentInfoListResult> results = JSON.parseArray(JSON.toJSONString(departments), GetDepartmentInfoListResult.class);
        return ResponseWrapper.markSuccess(results);
    }

    /**
     * 6、【新增/修改】新增/修改部门信息
     * @param param 表单信息
     * @return 修改情况
     */
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper saveDepartmentInfo(SaveDepartmentInfoParam param) {
        //获取对应部门的信息
        Department newDepartment = JSON.parseObject(JSON.toJSONString(param),Department.class);
        if(param.getAid() == -1){  //新增部门信息
            //对父部门的aid进行判断
            if(param.getFatherAid() == -1){
                newDepartment.setFatherAid(null);
                newDepartment.setLevel(0);
            }
            //新增部门信息
            int insert = departmentMapper.insert(newDepartment);
            if (insert >0){
                return ResponseWrapper.markSuccess("新增成功");
            }else {
                return ResponseWrapper.markSuccess("新增失败");
            }
        }
        else{  // 修改部门信息

            //通过aid查询出部门信息
            LambdaUpdateWrapper<Department> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Department::getAid,param.getAid());
            newDepartment.setAid(param.getAid());
            newDepartment.setName(param.getName());
            newDepartment.setStateId(param.getStateId());
            //对父部门的aid进行判断
            if (param.getFatherAid() == -1){
                newDepartment.setLevel(0);
                newDepartment.setFatherAid(null);
                updateWrapper.set(Department::getFatherAid,null);
            }else {
                //通过父部门的aid获取部门的aid
                LambdaQueryWrapper<Department> wrapper1 = new LambdaQueryWrapper<>();
                wrapper1.eq(Department::getAid,param.getFatherAid());
                Department department1 = departmentMapper.selectOne(wrapper1);
                newDepartment.setLevel(department1.getLevel()+1);
                newDepartment.setFatherAid(param.getFatherAid());
            }

            int update = departmentMapper.update(newDepartment,updateWrapper);
            if (update >0){
                return ResponseWrapper.markSuccess("修改成功");
            }else {
                return ResponseWrapper.markSuccess("修改失败");
            }
        }
    }

    /**
     * 7、【新增/修改】检查部门名称是否重复
     * @param param 部门aid和name
     * @return isExist
     */
    public ResponseWrapper checkDepartmentNameExist(CheckDepartmentNameExistParam param) {
        //获取部门的信息
        LambdaQueryWrapper<Department> getByName = new LambdaQueryWrapper<>();
        getByName.eq(Department::getName, param.getName());
        Department department = departmentMapper.selectOne(getByName);
        //获取对应部门的信息
        CheckDepartmentNameExistItem departmentInfo = JSON.parseObject(JSON.toJSONString(department), CheckDepartmentNameExistItem.class);
        CheckDepartmentNameExistResult result = new CheckDepartmentNameExistResult(departmentInfo, false);
        result.setIsExist(false);
        //对部门信息进行判断
        if (departmentInfo != null && department.getAid().intValue() != param.getAid().intValue()) {
            result.setIsExist(true);
        }
        if (!result.getIsExist()) {
            result.setDepartmentInfo(null);
        }
        return ResponseWrapper.markSuccess(result);
    }

    /**
     * 8、【删除】删除部门
     * @param param 部门aid
     * @return 操作结果
     */
    public ResponseWrapper delDepartment(DelDepartmentParam param) {
        //对部门信息进行判断
        if (departmentMapper.selectById(param.getAid()) != null) {
            departmentMapper.deleteById(param.getAid());
            return ResponseWrapper.markSuccess();
        } else {
            return ResponseWrapper.markCustom(FAILED, "该部门不存在!刷新页面!");
        }
    }

    /**
     * 9、检查部门父子关系
     * @param param 父部门aid和子部门aid
     * @return 能否关联
     */
    public ResponseWrapper checkDepartmentRelate(CheckDepartmentRelateParam param) {
        CheckDepartmentRelateResult result = new CheckDepartmentRelateResult();

        //对传入的部门aid进行判断
        if (param.getAid() == -1) {
            result.setIsDescendants(false);
            return ResponseWrapper.markSuccess(result);
        }
        // 先检查传过来的参数信息是否符合规范
        LambdaQueryWrapper<Department> departmentAid = new LambdaQueryWrapper<>();
        departmentAid.eq(Department::getAid, param.getAid());
        Department getDepartmentAid = departmentMapper.selectOne(departmentAid);
        if (getDepartmentAid == null) {
            throw new MyException("根据aid没有找到对应的部门信息，请刷新页面！");
        }

        LambdaQueryWrapper<Department> departmentFatherAid = new LambdaQueryWrapper<>();
        departmentFatherAid.eq(Department::getAid, param.getFatherAid());
        Department getDepartmentFatherAid = departmentMapper.selectOne(departmentFatherAid);

        //获取部门信息
        List<Department> departments = departmentMapper.selectList(null);
        int startAid = param.getAid();

        //循环父部门的aid
        while (param.getFatherAid() != null) {
            // 遍历寻找列表中的父级分类
            for (Department e : departments) {
                if (startAid == param.getFatherAid()) { // 形成闭环
                    result.setIsDescendants(true);
                    return ResponseWrapper.markSuccess(result);
                }
                if ((int)e.getAid() == param.getFatherAid()) {  // 找父部门
                    param.setAid(e.getAid());
                    param.setFatherAid(e.getFatherAid());
                    if(param.getFatherAid()==null) break;
                }
            }
        }
        result.setIsDescendants(false);
        return ResponseWrapper.markSuccess(result);
    }
}
